#include <gui/widget.h>




// ===============================================Widget========================================

Widget::Widget(Widget* parent, int32_t x, int32_t y, int32_t w, int32_t h,
            int32_t r, int32_t g, int32_t b): KeyboardEventHandler(),
parent(parent),
x(x),
y(y),
w(w),
h(h),
r(r),
g(g),
b(b)
{
    this->focusable = true;

}

Widget::~Widget()
{


}


     void Widget::GetFocus(Widget* widget){
        if(parent != 0)
            parent->GetFocus(widget);
     }

     
     void Widget::ModelToScreen(int32_t &x, int32_t &y){
            
            if(parent != 0)
                parent->ModelToScreen(x, y);
            x += this->x;
            y += this->y;
     }

    bool Widget::ContainsCoordinate(int32_t x, int32_t y){

        return this->x <= x && x < this->x + this->w && this->y <= y && y < this->y + this->h;

    }



     void Widget::Draw(GraphicsContext* gc){

        int32_t X = 0;
        int32_t Y = 0;
        ModelToScreen(X, Y);
        gc->FillRectangle(X, Y, w, h, r, g, b);

     }
     void Widget::OnMouseDwon(int32_t x, int32_t y,uint8_t button){

        if(focusable){
            GetFocus(this);
        }

     }
     void Widget::OnMouseUp(int32_t x, int32_t y,uint8_t button){

     }
     void Widget::OnMouseMove(int32_t oldX, int32_t oldY, int32_t newX, int32_t newY){

     }

     void Widget::OnKeyDown(char){

     }
     void Widget::OnKeyUp(char){

     }




// ===============================================CompositeWidget========================================
    CompositeWidget::CompositeWidget(Widget* parent, int32_t x, int32_t y, int32_t w, int32_t h,
        int32_t r, int32_t g, int32_t b):Widget(parent,  x,  y,  w,  h,
            r,  g,  b)
{
    
    focussedChild = 0;
    numChildren = 0;

}

CompositeWidget::~CompositeWidget()
{


}


     void CompositeWidget::GetFocus(Widget* widget){

            this->focussedChild = widget;
            if(parent != 0)
                parent->GetFocus(this);
     }

    void CompositeWidget::AddChild(Widget* widget){

        this->children[numChildren] = widget;
        this->numChildren++;

    }




     void CompositeWidget::Draw(GraphicsContext* gc){

        Widget::Draw(gc);
        for (int8_t i = 0; i < numChildren; i++)
        {
            children[i]->Draw(gc);
            /* code */
        }
        

     }
     void CompositeWidget::OnMouseDwon(int32_t x, int32_t y,uint8_t button){

        for (int8_t i = 0; i < numChildren; i++)
        {
            if(children[i]->ContainsCoordinate(x - this->x,y - this->y)){

                children[i]->OnMouseDwon(x - this->x,y - this->y, button);
            }
            /* code */
        }

     }
     void CompositeWidget::OnMouseUp(int32_t x, int32_t y,uint8_t button){

        for (int8_t i = 0; i < numChildren; i++)
        {
            if(children[i]->ContainsCoordinate(x - this->x,y - this->y)){

                children[i]->OnMouseUp(x - this->x,y - this->y, button);
            }
            /* code */
        }
     }
     void CompositeWidget::OnMouseMove(int32_t oldX, int32_t oldY, int32_t newX, int32_t newY){
        
        int8_t firstchild = -1;
        for (int8_t i = 0; i < numChildren; i++)
        {
            if(children[i]->ContainsCoordinate(oldX - this->x,oldY - this->y)){

                children[i]->OnMouseMove(oldX - this->x,oldY - this->y, newX - this->x, newY - this->y);
                firstchild = i;
                break;
            }
            /* code */
        }

        for (int8_t i = 0; i < numChildren; i++)
        {
            if(children[i]->ContainsCoordinate(newX - this->x, newY - this->y)){
                if(firstchild != i){

                children[i]->OnMouseMove(oldX - this->x,oldY - this->y, newX - this->x, newY - this->y);

                }
                break;
            }
            /* code */
        }

     }

     void CompositeWidget::OnKeyDown(char c){

        if(focussedChild != 0){
            focussedChild->OnKeyDown(c);
        }

     }
     void CompositeWidget::OnKeyUp(char c){

        if(focussedChild != 0){
            focussedChild->OnKeyUp(c);
        }

     }
